package cn.edu.xmut.chen.zhlg.zhlg.user.service.impl;

import cn.edu.xmut.chen.zhlg.common.framework.utils.AssertUtils;
import cn.edu.xmut.chen.zhlg.common.utils.CommonRequestUtils;
import cn.edu.xmut.chen.zhlg.common.utils.JwtUtil;
import cn.edu.xmut.chen.zhlg.common.utils.ResultType;
import cn.edu.xmut.chen.zhlg.zhlg.user.entity.User;
import cn.edu.xmut.chen.zhlg.zhlg.user.mapper.UserMapper;
import cn.edu.xmut.chen.zhlg.zhlg.user.param.UserLoginParam;
import cn.edu.xmut.chen.zhlg.zhlg.user.param.UserRegisterParam;
import cn.edu.xmut.chen.zhlg.zhlg.user.param.UserUpdateParam;
import cn.edu.xmut.chen.zhlg.zhlg.user.result.UserDetailResult;
import cn.edu.xmut.chen.zhlg.zhlg.user.result.UserInfoResult;
import cn.edu.xmut.chen.zhlg.zhlg.user.result.UserLoginResult;
import cn.edu.xmut.chen.zhlg.zhlg.user.service.UserService;
import cn.edu.xmut.chen.zhlg.zhlg.user.userenum.SexEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.UUID;

@RequiredArgsConstructor
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    
    // 文件上传目录配置
    private static final String UPLOAD_DIR = "D:/upload/avatar/";
    private static final String ACCESS_PATH = "/static/avatar/";

    @Override
    public String register(UserRegisterParam userRegisterParam) {
        String phone = userRegisterParam.getPhone();
        User exitUser = this.getByPhone(phone);
        String code = userRegisterParam.getCode();
        // 已经注册过的不用重新注册
        AssertUtils.assertNull(exitUser, ResultType.FAIL, "该电话号码已注册");
        //code验证
        AssertUtils.assertTrue(codeCheck(code,phone),ResultType.FAIL,"验证码错误");
        //注册操作
        User user = new User();
        user.setPhone(phone);
        user.setCreateTime(LocalDateTime.now());
        user.setRole(userRegisterParam.getRole());
        this.save(user);
        return JwtUtil.generateToken(user.getId());
    }

    @Override
    public String login(UserLoginParam userLoginParam) {
        String phone = userLoginParam.getPhone();
        User exitUser = this.getByPhone(phone);
        AssertUtils.assertNotNull(exitUser, ResultType.FAIL, "该电话号码未注册");
        String code = userLoginParam.getCode();
        //code验证
        AssertUtils.assertTrue(codeCheck(code,phone),ResultType.FAIL,"验证码错误");
        //用户注册验证
        return JwtUtil.generateToken(exitUser.getId());
    }

    @Override
    public UserLoginResult getDetail(String token) {
        String id = JwtUtil.validateToken(token);
        UserLoginResult result = new UserLoginResult();
        BeanUtils.copyProperties(this.getById(id), result);
        log.info("用户：{}", result);
        return result;
    }

    @Override
    public UserDetailResult getPersonalDetail() {
        String id = CommonRequestUtils.getLoginId();
        UserDetailResult result = new UserDetailResult();
        BeanUtils.copyProperties(this.getById(id), result);
        System.out.println(result);
        return result;
    }

    @Override
    public UserDetailResult getDetailByUserId(String userId) {
        UserDetailResult result = new UserDetailResult();
        BeanUtils.copyProperties(userMapper.selectById(userId), result);
        return result;
    }

    private Boolean codeCheck(String code,String phone) {
        AssertUtils.assertNotNull(code, ResultType.FAIL,"验证码为空");
        // 手机号后四位作为验证码登录
        return phone.length() >= 4 && phone.substring(phone.length() - 4).equals(code);
    }

    @Override
    public User getByPhone(String phone) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        return this.getOne(queryWrapper);
    }

    @Override
    public UserInfoResult getUserInfo(String userId) {
        User user = this.getById(userId);
        if (user == null) {
            return null;
        }
        
        UserInfoResult result = new UserInfoResult();
        BeanUtils.copyProperties(user, result);
        result.setSex(user.getSex().name());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserInfo(String userId, UserUpdateParam param) {
        User user = this.getById(userId);
        if (user == null) {
            return false;
        }

        // 更新用户信息
        if (param.getPic() != null) {
            user.setPic(param.getPic());
        }
        if (param.getNickName() != null) {
            user.setNickName(param.getNickName());
        }
        if (param.getSex() != null) {
            user.setSex(SexEnum.valueOf(param.getSex()));
        }
        if (param.getRegion() != null) {
            user.setRegion(param.getRegion());
        }
        if (param.getBio() != null) {
            user.setBio(param.getBio());
        }

        return this.updateById(user);
    }

    @Override
    public String uploadAvatar(MultipartFile file) {
        // 验证文件是否为空
        if (file == null || file.isEmpty()) {
            AssertUtils.assertTrue(false, ResultType.FAIL,"上传文件为空");
        }

        // 验证文件类型
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        if (!Arrays.asList("jpg", "jpeg", "png", "gif").contains(fileExtension)) {
            AssertUtils.assertTrue(false,ResultType.FAIL,"上传文件格式有误");
        }

        // 验证文件大小（10MB）
        if (file.getSize() > 10 * 1024 * 1024) {
            AssertUtils.assertTrue(false,ResultType.FAIL,"上传文件超过10MB");
        }

        try {
            // 生成新的文件名
            String newFilename = UUID.randomUUID().toString() + "." + fileExtension;
            
            // 确保上传目录存在
            File uploadDir = new File(UPLOAD_DIR);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }
            
            // 保存文件
            File destFile = new File(UPLOAD_DIR + newFilename);
            file.transferTo(destFile);
            
            // 返回可访问的URL路径
            return ACCESS_PATH + newFilename;
            
        } catch (IOException e) {
            log.error("头像上传失败", e);
            AssertUtils.assertTrue(false,ResultType.FAIL,"头像上传失败");
        } catch (Exception e) {
            log.error("头像上传处理异常", e);
            AssertUtils.assertTrue(false,ResultType.FAIL,"头像上传处理异常");
        }

        return null;
    }

}
